use std::io::stdin;

#[derive(Debug)]
enum VisitorAction{
    Accept,
    AcceptWithNote { note: String },
    Refuse,
    Probation,
}

#[derive(Debug)]
struct Visitor{
    name: String,
    action: VisitorAction,
    age: i8,
}

impl Visitor{
    fn new(name: &str, action: VisitorAction, age: i8) -> Self {
        Self {
            name: name.to_lowercase(),
            action,
            age,
        }
    }

    fn greet_visitor(&self){
        match &self.action{
            VisitorAction::Accept => println!("Welcome to the tree house, {}", self.name),
            VisitorAction::AcceptWithNote { note } => {
                println!("Wellcome to the treehouse, {}", self.name);
                println!("{}", note);

                if self.age < 21{
                    println!("Do not serve alcohol to {}", self.name);
                }
            }
            VisitorAction::Probation => println!("{} is now a probationary member", self.name),
            VisitorAction::Refuse => println!("Do not allow {} in!", self.name),
        }
    }
}


fn what_is_your_name() -> String {

    let mut your_name = String::new();

    stdin()
        .read_line(&mut your_name)
        .expect("Failed to read line");
    
    return your_name.trim().to_lowercase();
}

fn main() {

    let mut visitor_list: Vec<Visitor> = vec![
        Visitor::new("Bert", VisitorAction::Accept, 45),
        Visitor::new("Steve", VisitorAction::AcceptWithNote { note: String::from("Lactose-free milk is in the fridge") }, 15),
        Visitor::new("Fred", VisitorAction::Refuse, 30),
    ];

    loop{

        println!("Hello, what's your name!");

        let name: String = what_is_your_name();

        let visitor: Option<&Visitor> = visitor_list.iter().find(|v: &&Visitor| v.name == name);

        match visitor{
            Some(v) => v.greet_visitor(),
            None => {
                if name.is_empty(){
                    println!("The final list of visitors:");
                    println!("{:#?}", visitor_list);
                    break;
                }else{
                    println!("{} is not on the visitor list.", name);
                    visitor_list.push(Visitor::new(&name, VisitorAction::Probation, 0));
                }

            }
        }
    }

}
